﻿using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using OtherDevice;
using System.Diagnostics;
using CommonTools;
using System.Threading;
using BaseDll;
using UserData;
using System;
using MotionIoLib;
using Newtonsoft.Json;

namespace ModuleUnit
{
    public class Config_Disp
    {
        [Category("工站参数"), DisplayName("1.点胶IO "), Description("点胶IO ")]
        public string str_点胶IO { set; get; } = "";
        [Category("工站参数"), DisplayName("21.视觉控制"), Description("视觉控制")]
        public string str_VisionControl { set; get; } = "";
        [Category("工站参数"), DisplayName("23.点胶相机编号"), Description("点胶相机编号")]
        public int n_点胶相机编号 { set; get; } = 2;
        [Category("工站参数"), DisplayName("26.点胶定位任务号"), Description("点胶定位任务号")]
        public string n_点胶定位任务号 { set; get; } = "";
        [Category("工站参数"), DisplayName("26.胶型检测任务号"), Description("胶型检测任务号")]
        public string n_胶型检测任务号 { set; get; } = "";
        [Category("工站参数"), DisplayName("26.胶针定位任务号"), Description("胶针定位任务号")]
        public string n_胶针定位任务号 { set; get; } = "";
        [Category("工站参数"), DisplayName("26.点胶相机九点标定任务号"), Description("点胶相机九点标定任务号")]
        public string n_点胶相机九点标定任务号 { set; get; } = "";
        [Category("工站参数"), DisplayName("18.光源控制器"), Description("光源控制器")]
        public string str_光源控制器 { set; get; } = "";
    }
    [Description("点胶")]
    public class Module_Disp : ModuleBase
    {
        public Config_Disp config = null;
        public Module_Disp(object config, string strName) : base(strName)
        {
            VisionDataMgr.GetInstance().AddVisionCoordinate(str_ModuleName);
            MesureHighMgr.GetInstance().AddMesureHigh(str_ModuleName);

            if (config == null)
            {
                this.config = new Config_Disp();
            }
            else
            {
                this.config = JsonConvert.DeserializeObject<Config_Disp>(config.ToString());

            }
            this.obj_Config = this.config;
        }
        LightCtrlBase Device_光源控制器
        {
            set { }
            get
            {
                return DeviceMgr.GetInstance().Function_获取串口(config.str_光源控制器) as LightCtrlBase;
            }
        }
        Vision_Base Device_视觉
        {
            set { }
            get
            {
                return DeviceMgr.GetInstance().Function_获取网口(config.str_VisionControl) as OtherDevice.Vision_Base;
            }
        }

        double[] VX = new double[9];
        double[] VY = new double[9];
        double[] MX = new double[9];
        double[] MY = new double[9];
        public bool Function_点胶相机九点标定(int n_Time, XYUPoint point_Snap, XYUPoint point_Center, ref XYUPoint pointPix)
        {
            string strMsg = "";
            if (config.n_点胶相机编号 < 0)
                strMsg = config.n_点胶相机九点标定任务号;
            else
                strMsg = $"{config.n_点胶相机编号},{config.n_点胶相机九点标定任务号}";

            if (n_Time >= 9)
                return false;
            if (Device_视觉.VisionControlUsing(strMsg, out string[] result,null) != 0)
            {
                return false;
            }
            if (result.Length < 2)
                return false;
            string[] ListValue = result;
            pointPix.x = Convert.ToDouble(ListValue[0]);
            pointPix.y = Convert.ToDouble(ListValue[1]);

            VX[n_Time] = Convert.ToDouble(ListValue[0]);
            VY[n_Time] = Convert.ToDouble(ListValue[1]);
            MX[n_Time] = point_Snap.x - point_Center.x;
            MY[n_Time] = point_Snap.y - point_Center.y;
            if (n_Time == 8)
            {
                VisionDataMgr.GetInstance().setCameraCoordinate(str_ModuleName, VX, VY, MX, MY);
                VisionDataMgr.GetInstance().Save();
            }
            return true;
        }
        public bool Function_胶针标定(XYUPoint point_Snap, XYUPoint point_dress, ref XYUPoint pointPix)
        {
            string strMsg = "";
            if (config.n_点胶相机编号 < 0)
                strMsg = config.n_胶针定位任务号;
            else
                strMsg = $"{config.n_点胶相机编号},{config.n_胶针定位任务号}";


            if (Device_视觉.VisionControlUsing(strMsg, out string[] result,null) == 0)
            {
                if (result.Length < 2)
                    return false;

                XYUPoint VisionCCDPix = new XYUPoint();
                string[] ListValue = result;
                pointPix.x = Convert.ToDouble(ListValue[0]);
                pointPix.y = Convert.ToDouble(ListValue[1]);
                VisionCCDPix.x = Convert.ToDouble(ListValue[0]);
                VisionCCDPix.y = Convert.ToDouble(ListValue[1]);
                VisionDataMgr.GetInstance().setVector_DispPin_DispCCD(str_ModuleName, point_Snap, point_dress, VisionCCDPix);
                VisionDataMgr.GetInstance().Save();
                return true;
            }
            else
            {
                return false;
            }

        }
        public bool Function_点胶定位(XYUPoint point_Snap, ref XYUPoint PointResult, Action actionMove = null)
        {
            string strMsg = "";
            if (config.n_点胶相机编号 < 0)
                strMsg = config.n_点胶定位任务号;
            else
                strMsg = $"{config.n_点胶相机编号},{config.n_点胶定位任务号}";


            if (Device_视觉.VisionControlUsing(strMsg, out string[] result, actionMove) == 0)
            {
                if (result.Length < 3)
                    return false;

                XYUPoint CenterPixel = new XYUPoint();
                CenterPixel.x = Convert.ToDouble(result[0]);
                CenterPixel.y = Convert.ToDouble(result[1]);
                CenterPixel.u = Convert.ToDouble(result[2]);
                VisionDataMgr.GetInstance().setVector_DispCCD_Senser(str_ModuleName, point_Snap, CenterPixel);
                VisionDataMgr.GetInstance().getDispPin_Tagert(str_ModuleName, point_Snap, CenterPixel, out PointResult);
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool Function_胶型检测(ref double d_Area,ref double d_MaxWidth,ref double d_MinWidth,ref double d_Average,Action actionMove=null)
        {
            string strMsg = "";
            if (config.n_点胶相机编号 < 0)
                strMsg = config.n_胶型检测任务号;
            else
                strMsg = $"{config.n_点胶相机编号},{config.n_胶型检测任务号}";


            if (Device_视觉.VisionControlUsing(strMsg, out string[] result, actionMove) == 0)
            {
                string[] ListValue = result;
                if (ListValue.Length < 4)
                    return false;
                d_Area =Math.Round( VisionDataMgr.GetInstance().Funciton_换算像素至面积(str_ModuleName, Convert.ToDouble(ListValue[0])),3);
                d_MinWidth = Math.Round(VisionDataMgr.GetInstance().Funciton_换算像素至机械值(str_ModuleName, Convert.ToDouble(ListValue[1])), 3);
                d_MaxWidth = Math.Round(VisionDataMgr.GetInstance().Funciton_换算像素至机械值(str_ModuleName, Convert.ToDouble(ListValue[2])), 3);
                d_Average = Math.Round(VisionDataMgr.GetInstance().Funciton_换算像素至机械值(str_ModuleName, Convert.ToDouble(ListValue[3])), 3);
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool Function_记录针尖高度(double d_PinPosZ, double d_HighPosZ,double d_HighValue)
        {
            MesureHighMgr.GetInstance().SetOriTestHighValue(str_ModuleName, d_HighValue);
            MesureHighMgr.GetInstance().SetOriDispZPos(str_ModuleName, d_HighPosZ);
            MesureHighMgr.GetInstance().SetOriDispPinHigh(str_ModuleName, d_PinPosZ);
            MesureHighMgr.GetInstance().Save();
            return true;
        }
        public double Function_测高换算(double d_NowPosZ, double d_NowHighValue)
        {
            return MesureHighMgr.GetInstance().GetNowNozzleHigh(str_ModuleName, d_NowHighValue, d_NowPosZ);
        }

        public bool Function_DispCircle(int n_AxisX, int n_AxisY, double d_radiue,
                                  bool b_是否吐胶,int n_点胶延时,
                                  double d_DispVel, double d_DispRunAngle,double d_EndRunAngle,ref string strError)
        {
            bool brtnExc = true;
            //获取圆心坐标---起始点在X+半径
            double CirclePosX = MotionMgr.GetInstace().GetAxisActPos(n_AxisX) - d_radiue;
            double CirclePosY = MotionMgr.GetInstace().GetAxisActPos(n_AxisY);

            MotionMgr.GetInstace().ClearBufMove("点胶群组");
            MotionMgr.GetInstace().RestGpErr("点胶群组");

            MotionMgr.GetInstace().AddAxisToGroup("点胶群组", new int[] { n_AxisX, n_AxisY });
            //点胶加速度可考虑开放出来
            brtnExc &= MotionMgr.GetInstace().SetBufMoveParam("点胶群组", d_DispVel, 0, 0.1, 0.1,ref strError);
            if (!brtnExc)
            {
                return false;
            }
            if (b_是否吐胶)
            {
                MotionMgr.GetInstace().AddBufIo("点胶群组", config.str_点胶IO, true);
                MotionMgr.GetInstace().AddBufDelay("点胶群组", n_点胶延时);

            }
            else
            {
                MotionMgr.GetInstace().AddBufIo("点胶群组", config.str_点胶IO, false);
            }
            int CircleCount = 1;
            if (d_DispRunAngle % 360 == 0)
                d_DispRunAngle = d_DispRunAngle + 0.1;
            CircleCount = 1 + (int)(d_DispRunAngle) / 360;
            double circleDx = d_radiue * Math.Cos(d_DispRunAngle * Math.PI / 180);
            double circleDy = d_radiue * Math.Sin(d_DispRunAngle * Math.PI / 180);

            double endX = CirclePosX + circleDx;
            double endY = CirclePosY + circleDy;
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { CirclePosX, CirclePosY }, new double[2] { endX, endY }, CircleCount);
            MotionMgr.GetInstace().AddBufIo("点胶群组", config.str_点胶IO, false);
            CircleCount = 1;
            if (d_EndRunAngle % 360 == 0)
                d_EndRunAngle = d_EndRunAngle + 0.1;
            CircleCount = 1 + (int)(d_EndRunAngle) / 360;
            double aheadEndDispX = d_radiue * Math.Cos((d_DispRunAngle + d_EndRunAngle) * Math.PI / 180);
            double aheadEndDispY = d_radiue * Math.Sin((d_DispRunAngle + d_EndRunAngle) * Math.PI / 180);
            double closeX = CirclePosX + aheadEndDispX;
            double closeY = CirclePosY + aheadEndDispY;
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { CirclePosX, CirclePosY }, new double[2] { closeX, closeY }, CircleCount);
            brtnExc &= MotionMgr.GetInstace().BufTrans("点胶群组",ref strError);
            if (!brtnExc)
            {
                return false;
            }

            MotionMgr.GetInstace().AddBufEnd("点胶群组");
            MotionMgr.GetInstace().BufStart("点胶群组");
            MotionMgr.GetInstace().ClearBufMove("点胶群组");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Restart();
            while (true)
            {
                double x = MotionMgr.GetInstace().GetAxisActPos(n_AxisX);
                double y = MotionMgr.GetInstace().GetAxisActPos(n_AxisY);
                if (MotionMgr.GetInstace().IsAxisNormalStop(n_AxisX) == AxisState.NormalStop && MotionMgr.GetInstace().IsAxisNormalStop(n_AxisY) == AxisState.NormalStop)
                {
                    break;
                }
                if (stopwatch.ElapsedMilliseconds > 30000)
                {
                    IOMgr.GetInstace().WriteIoBit(config.str_点胶IO, false);
                    return false;
                }
            }
            IOMgr.GetInstace().WriteIoBit(config.str_点胶IO, false);
            return brtnExc;
        }
        public bool Function_DispRectangle(int n_AxisX, int n_AxisY, double dRx, double dRy,double d_Angle,
                                           double d_拐弯半径,bool b_是否吐胶, int n_点胶延时,
                                           double d_DispVel, double d_EndRunLength,ref string strError)
        {
            bool brtnExc = true;
             //获取圆心坐标---起始点在X+半径
            double CenterPosX = MotionMgr.GetInstace().GetAxisActPos(n_AxisX) - dRx * Math.Cos(d_Angle / 180 * Math.PI);
            double CenterPosY = MotionMgr.GetInstace().GetAxisActPos(n_AxisY) - dRx * Math.Sin(d_Angle / 180 * Math.PI);
            MotionMgr.GetInstace().ClearBufMove("点胶群组");
            MotionMgr.GetInstace().RestGpErr("点胶群组");

            MotionMgr.GetInstace().AddAxisToGroup("点胶群组", new int[] { n_AxisX, n_AxisY });
            //点胶加速度可考虑开放出来
            brtnExc &= MotionMgr.GetInstace().SetBufMoveParam("点胶群组", d_DispVel, 0, 0.1, 0.1,ref strError);
            if(!brtnExc)
            {
                return false;
            }
            if (b_是否吐胶)
            {
                MotionMgr.GetInstace().AddBufIo("点胶群组",config.str_点胶IO, true);
                MotionMgr.GetInstace().AddBufDelay("点胶群组", n_点胶延时);
            }
            else
            {
                MotionMgr.GetInstace().AddBufIo("点胶群组", config.str_点胶IO, false);

            }
            XYUPoint Point_圆弧起点_1 = new XYUPoint();
            XYUPoint Point_圆弧中心_1 = new XYUPoint();
            XYUPoint Point_圆弧终点_1 = new XYUPoint();
            XYUPoint Point_圆弧起点_2 = new XYUPoint();
            XYUPoint Point_圆弧中心_2 = new XYUPoint();
            XYUPoint Point_圆弧终点_2 = new XYUPoint();
            XYUPoint Point_圆弧起点_3 = new XYUPoint();
            XYUPoint Point_圆弧中心_3 = new XYUPoint();
            XYUPoint Point_圆弧终点_3 = new XYUPoint();
            XYUPoint Point_圆弧起点_4 = new XYUPoint();
            XYUPoint Point_圆弧中心_4 = new XYUPoint();
            XYUPoint Point_圆弧终点_4 = new XYUPoint();
            XYUPoint Point_关胶处 = new XYUPoint();

            XYUPoint Point_模型圆弧起点_1 = new XYUPoint();
            XYUPoint Point_模型圆弧中心_1 = new XYUPoint();
            XYUPoint Point_模型圆弧终点_1 = new XYUPoint();
            XYUPoint Point_模型圆弧起点_2 = new XYUPoint();
            XYUPoint Point_模型圆弧中心_2 = new XYUPoint();
            XYUPoint Point_模型圆弧终点_2 = new XYUPoint();
            XYUPoint Point_模型圆弧起点_3 = new XYUPoint();
            XYUPoint Point_模型圆弧中心_3 = new XYUPoint();
            XYUPoint Point_模型圆弧终点_3 = new XYUPoint();
            XYUPoint Point_模型圆弧起点_4 = new XYUPoint();
            XYUPoint Point_模型圆弧中心_4 = new XYUPoint();
            XYUPoint Point_模型圆弧终点_4 = new XYUPoint();
            XYUPoint Point_模型关胶处 = new XYUPoint();

            Point_模型圆弧起点_1.x = dRx;
            Point_模型圆弧起点_1.y = dRy - d_拐弯半径;
            Point_模型圆弧中心_1.x = dRx - d_拐弯半径;
            Point_模型圆弧中心_1.y = dRy - d_拐弯半径;
            Point_模型圆弧终点_1.x = dRx - d_拐弯半径;
            Point_模型圆弧终点_1.y = dRy;

            Point_模型圆弧起点_2.x = -dRx + d_拐弯半径;
            Point_模型圆弧起点_2.y = dRy;
            Point_模型圆弧中心_2.x = -dRx + d_拐弯半径;
            Point_模型圆弧中心_2.y = dRy - d_拐弯半径;
            Point_模型圆弧终点_2.x = -dRx;
            Point_模型圆弧终点_2.y = dRy - d_拐弯半径;

            Point_模型圆弧起点_3.x = -dRx;
            Point_模型圆弧起点_3.y = -dRy + d_拐弯半径;
            Point_模型圆弧中心_3.x = -dRx + d_拐弯半径;
            Point_模型圆弧中心_3.y = -dRy + d_拐弯半径;
            Point_模型圆弧终点_3.x = -dRx + d_拐弯半径;
            Point_模型圆弧终点_3.y = -dRy;

            Point_模型圆弧起点_4.x = dRx - d_拐弯半径;
            Point_模型圆弧起点_4.y = -dRy;
            Point_模型圆弧中心_4.x = dRx - d_拐弯半径;
            Point_模型圆弧中心_4.y = -dRy + d_拐弯半径;
            Point_模型圆弧终点_4.x = dRx;
            Point_模型圆弧终点_4.y = -dRy + d_拐弯半径;

            Point_模型关胶处.x = dRx;
            Point_模型关胶处.y = d_EndRunLength;

            XYUPoint PointOri = new XYUPoint(0, 0, 0);
            XYUPoint PointNow = new XYUPoint(CenterPosX, CenterPosY, d_Angle);
            Point_圆弧起点_1 = TransData(PointOri, PointNow, Point_模型圆弧起点_1);
            Point_圆弧中心_1 = TransData(PointOri, PointNow, Point_模型圆弧中心_1);
            Point_圆弧终点_1 = TransData(PointOri, PointNow, Point_模型圆弧终点_1);
            Point_圆弧起点_2 = TransData(PointOri, PointNow, Point_模型圆弧起点_2);
            Point_圆弧中心_2 = TransData(PointOri, PointNow, Point_模型圆弧中心_2);
            Point_圆弧终点_2 = TransData(PointOri, PointNow, Point_模型圆弧终点_2);
            Point_圆弧起点_3 = TransData(PointOri, PointNow, Point_模型圆弧起点_3);
            Point_圆弧中心_3 = TransData(PointOri, PointNow, Point_模型圆弧中心_3);
            Point_圆弧终点_3 = TransData(PointOri, PointNow, Point_模型圆弧终点_3);
            Point_圆弧起点_4 = TransData(PointOri, PointNow, Point_模型圆弧起点_4);
            Point_圆弧中心_4 = TransData(PointOri, PointNow, Point_模型圆弧中心_4);
            Point_圆弧终点_4 = TransData(PointOri, PointNow, Point_模型圆弧终点_4);

            Point_关胶处 = TransData(PointOri, PointNow, Point_模型关胶处);
            XYUPoint Point_Now = new XYUPoint();
            Point_Now.x = MotionMgr.GetInstace().GetAxisActPos(n_AxisX);
            Point_Now.y = MotionMgr.GetInstace().GetAxisActPos(n_AxisY);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_Now.x, Point_Now.y },
                                                            new double[2] { Point_圆弧起点_1.x, Point_圆弧起点_1.y }, 1);

            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧中心_1.x, Point_圆弧中心_1.y },
                                                                        new double[2] { Point_圆弧终点_1.x, Point_圆弧终点_1.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧终点_1.x, Point_圆弧终点_1.y },
                                                                        new double[2] { Point_圆弧起点_2.x, Point_圆弧起点_2.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧中心_2.x, Point_圆弧中心_2.y },
                                                                        new double[2] { Point_圆弧终点_2.x, Point_圆弧终点_2.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧终点_2.x, Point_圆弧终点_2.y },
                                                                        new double[2] { Point_圆弧起点_3.x, Point_圆弧起点_3.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧中心_3.x, Point_圆弧中心_3.y },
                                                                        new double[2] { Point_圆弧终点_3.x, Point_圆弧终点_3.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧终点_3.x, Point_圆弧终点_3.y },
                                                                        new double[2] { Point_圆弧起点_4.x, Point_圆弧起点_4.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Arc2dAbsCW, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧中心_4.x, Point_圆弧中心_4.y },
                                                                        new double[2] { Point_圆弧终点_4.x, Point_圆弧终点_4.y }, 1);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_圆弧终点_4.x, Point_圆弧终点_4.y },
                                                                        new double[2] { Point_Now.x, Point_Now.y }, 1);
            MotionMgr.GetInstace().AddBufIo("点胶群组", config.str_点胶IO, false);
            MotionMgr.GetInstace().AddBufMove("点胶群组", BufMotionType.buf_Line2dAbs, 0, 2, d_DispVel, 0, new double[2] { Point_Now.x, Point_Now.y },
                                                                       new double[2] { Point_关胶处.x, Point_关胶处.y }, 1);
            brtnExc &= MotionMgr.GetInstace().BufTrans("点胶群组",ref strError);
            if (!brtnExc)
            {
                return brtnExc;
            }
            MotionMgr.GetInstace().AddBufEnd("点胶群组");
            brtnExc &= MotionMgr.GetInstace().BufStart("点胶群组");
            MotionMgr.GetInstace().ClearBufMove("点胶群组");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Restart();
            while (true)
            {
                double x = MotionMgr.GetInstace().GetAxisActPos(n_AxisX);
                double y = MotionMgr.GetInstace().GetAxisActPos(n_AxisY);
                if (MotionMgr.GetInstace().IsAxisNormalStop(n_AxisX) == AxisState.NormalStop && MotionMgr.GetInstace().IsAxisNormalStop(n_AxisY) == AxisState.NormalStop)
                {
                    break;
                }
                if (stopwatch.ElapsedMilliseconds > 30000)
                {
                    IOMgr.GetInstace().WriteIoBit(config.str_点胶IO, false);
                    return false;
                }
            }
            IOMgr.GetInstace().WriteIoBit(config.str_点胶IO, false);
            return brtnExc;
        }

        private XYUPoint TransData(XYUPoint PointOri, XYUPoint PointNow, XYUPoint Point_模型)
        {
            double angleChange = PointNow.u - PointOri.u;
            angleChange = angleChange / 180.0 * Math.PI;
            double RotateX = PointOri.x + (Point_模型.x - PointOri.x) * Math.Cos(angleChange) - (Point_模型.y - PointOri.y) * Math.Sin(angleChange);
            double RotateY = PointOri.y + (Point_模型.x - PointOri.x) * Math.Sin(angleChange) + (Point_模型.y - PointOri.y) * Math.Cos(angleChange);
            XYUPoint Point_Tagret = new XYUPoint();
            Point_Tagret.x = PointNow.x - PointOri.x + RotateX;
            Point_Tagret.y = PointNow.y - PointOri.y + RotateY;
            return Point_Tagret;
        }

    }
}